/**
 * @file camera_capture_thread.c
 * @brief 摄像头采集线程实现
 * @version 1.0
 * @date 2025-04-29
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#include <time.h>

#include "camera_capture_thread.h"
#include "camera_capture_mode.h"
#include "thread_utils.h"
#include "system_utils.h"

// 全局变量定义
pthread_t g_capture_thread = 0;
volatile CaptureThreadState g_capture_thread_state = CAPTURE_THREAD_IDLE;
volatile bool g_capture_thread_exit = false;

// 线程参数结构
typedef struct {
    int capture_count;  // 采集次数
} CaptureThreadParams;

// 互斥锁，用于保护线程状态
static pthread_mutex_t g_capture_thread_mutex = PTHREAD_MUTEX_INITIALIZER;

// 线程函数前向声明
static void* camera_capture_thread_func(void *arg);

/**
 * @brief 设置线程状态
 * 
 * @param state 新状态
 */
static void set_thread_state(CaptureThreadState state) {
    pthread_mutex_lock(&g_capture_thread_mutex);
    g_capture_thread_state = state;
    pthread_mutex_unlock(&g_capture_thread_mutex);
}

/**
 * @brief 启动摄像头采集线程
 * 
 * @param capture_count 采集次数，-1表示无限采集
 * @return int 成功返回0，失败返回非0
 */
int start_camera_capture_thread(int capture_count) {
    // 检查线程是否已经在运行
    if (g_capture_thread_state == CAPTURE_THREAD_RUNNING) {
        log_message(LOG_LEVEL_WARNING, "摄像头采集线程已经在运行");
        return 0;
    }
    
    // 重置退出标志
    g_capture_thread_exit = false;
    
    // 设置线程状态为空闲
    set_thread_state(CAPTURE_THREAD_IDLE);
    
    // 创建线程参数
    CaptureThreadParams* params = (CaptureThreadParams*)malloc(sizeof(CaptureThreadParams));
    if (!params) {
        log_message(LOG_LEVEL_ERROR, "无法分配摄像头采集线程参数内存");
        return -1;
    }
    
    // 设置参数
    params->capture_count = capture_count;
    
    // 创建线程
    int ret = create_thread(&g_capture_thread, camera_capture_thread_func, params, "摄像头采集");
    if (ret != 0) {
        log_message(LOG_LEVEL_ERROR, "创建摄像头采集线程失败: %d", ret);
        free(params);
        return -1;
    }
    
    log_message(LOG_LEVEL_INFO, "摄像头采集线程已启动, 计划采集次数: %d", 
               capture_count < 0 ? 0 : capture_count);
    
    return 0;
}

/**
 * @brief 停止摄像头采集线程
 * 
 * @return int 成功返回0，失败返回非0
 */
int stop_camera_capture_thread(void) {
    // 检查线程是否在运行
    if (g_capture_thread_state != CAPTURE_THREAD_RUNNING && g_capture_thread == 0) {
        log_message(LOG_LEVEL_WARNING, "摄像头采集线程未在运行");
        return 0;
    }
    
    // 设置退出标志
    g_capture_thread_exit = true;
    
    // 设置线程状态为正在停止
    set_thread_state(CAPTURE_THREAD_STOPPING);
    
    log_message(LOG_LEVEL_INFO, "正在停止摄像头采集线程...");
    
    // 等待线程结束
    int ret = wait_camera_capture_thread(5000);  // 等待最多5秒
    if (ret != 0) {
        log_message(LOG_LEVEL_WARNING, "等待摄像头采集线程结束超时");
        
        // 强制取消线程
        if (g_capture_thread != 0) {
            cancel_thread(g_capture_thread);
            join_thread(g_capture_thread, NULL);
            g_capture_thread = 0;
        }
    }
    
    set_thread_state(CAPTURE_THREAD_STOPPED);
    log_message(LOG_LEVEL_INFO, "摄像头采集线程已停止");
    
    return 0;
}

/**
 * @brief 获取摄像头采集线程状态
 * 
 * @return CaptureThreadState 线程状态
 */
CaptureThreadState get_camera_capture_thread_state(void) {
    CaptureThreadState state;
    
    pthread_mutex_lock(&g_capture_thread_mutex);
    state = g_capture_thread_state;
    pthread_mutex_unlock(&g_capture_thread_mutex);
    
    return state;
}

/**
 * @brief 等待摄像头采集线程结束
 * 
 * @param timeout_ms 超时时间(毫秒)，-1表示无限等待
 * @return int 成功返回0，超时返回1，失败返回-1
 */
int wait_camera_capture_thread(int timeout_ms) {
    // 检查线程是否存在
    if (g_capture_thread == 0) {
        return 0;  // 线程不存在，视为成功
    }
    
    if (timeout_ms < 0) {
        // 无限等待
        return join_thread(g_capture_thread, NULL);
    } else {
        // 有限等待
        time_t start_time = time(NULL);
        int elapsed_ms = 0;
        
        while (elapsed_ms < timeout_ms) {
            // 检查线程状态
            if (get_camera_capture_thread_state() == CAPTURE_THREAD_STOPPED) {
                join_thread(g_capture_thread, NULL);
                g_capture_thread = 0;
                return 0;
            }
            
            // 休眠100毫秒
            thread_sleep(100);
            
            // 计算已经过的时间
            elapsed_ms = (int)((time(NULL) - start_time) * 1000);
        }
        
        // 超时
        return 1;
    }
}

/**
 * @brief 摄像头采集线程函数
 * 
 * @param arg 线程参数
 * @return void* 线程返回值
 */
static void* camera_capture_thread_func(void *arg) {
    CaptureThreadParams* params = (CaptureThreadParams*)arg;
    int capture_count = params->capture_count;
    int result = 0;
    
    // 释放参数内存
    free(params);
    params = NULL;
    
    // 设置线程为可取消状态
    set_thread_cancel_state(1);
    set_thread_cancel_type(0);
    
    log_message(LOG_LEVEL_INFO, "摄像头采集线程已启动, 计划采集次数: %d", 
               capture_count < 0 ? 0 : capture_count);
    
    // 设置线程状态为运行中
    set_thread_state(CAPTURE_THREAD_RUNNING);
    
    // 初始化摄像头捕获模式
    if (init_camera_capture_mode() != 0) {
        log_message(LOG_LEVEL_ERROR, "初始化摄像头捕获模式失败");
        set_thread_state(CAPTURE_THREAD_ERROR);
        return (void*)(intptr_t)-1;
    }
    
    // 运行摄像头捕获
    log_message(LOG_LEVEL_INFO, "开始捕获3个摄像头图像，共%d次", capture_count);
    
    // 在运行摄像头捕获前检查退出标志
    if (!g_capture_thread_exit) {
        result = run_camera_capture_mode(capture_count);
    }
    
    // 清理资源
    cleanup_camera_capture_mode();
    
    // 检查结果
    if (result != 0) {
        log_message(LOG_LEVEL_ERROR, "摄像头捕获失败");
        set_thread_state(CAPTURE_THREAD_ERROR);
        return (void*)(intptr_t)-1;
    }
    
    // 设置线程状态为已停止
    set_thread_state(CAPTURE_THREAD_STOPPED);
    log_message(LOG_LEVEL_INFO, "摄像头采集线程已完成");
    
    return NULL;
} 